import tkinter as tk
from tkinter import scrolledtext, ttk, messagebox, filedialog, simpledialog
import json
import subprocess
import re
import os
import threading
import datetime

class LOPKTerminal:
    def __init__(self, root):
        self.root = root
        self.root.title("LOPK终端")
        self.root.geometry("800x600")
        self.root.resizable(True, True)

        # 设置字体以支持中文显示
        self.font = ('SimHei', 10)

        # 创建标签页控件用于终端和调试台
        self.notebook = ttk.Notebook(root)
        self.notebook.pack(expand=True, fill='both', padx=5, pady=5)

        # 终端输出标签页
        self.terminal_frame = ttk.Frame(self.notebook)
        self.notebook.add(self.terminal_frame, text="终端输出")
        self.output_area = scrolledtext.ScrolledText(self.terminal_frame, font=self.font, wrap=tk.WORD, bg='black', fg='white')
        self.output_area.pack(expand=True, fill='both')
        self.output_area.config(state=tk.DISABLED)

        # 调试信息标签页
        self.debug_frame = ttk.Frame(self.notebook)
        self.notebook.add(self.debug_frame, text="调试信息")
        self.debug_area = scrolledtext.ScrolledText(self.debug_frame, font=self.font, wrap=tk.WORD, bg='black', fg='lightgreen')
        self.debug_area.pack(expand=True, fill='both')
        self.debug_area.config(state=tk.DISABLED)

        # 调试标志
        self.verbose_debug = False
        self.command_library = {}

        # 命令历史记录
        self.command_history = []
        self.history_index = -1
        self.current_dir = os.getcwd()
        # 命令记录相关
        self.command_records = []  # 存储所有命令记录
        self.command_history_file = os.path.join(os.path.expanduser("~"), ".lopk_terminal_commands.json")
        self.load_command_records()  # 加载保存的命令记录

        # 创建菜单栏
        self.create_menu_bar()

        # 创建命令输入区域
        input_frame = ttk.Frame(root)
        input_frame.pack(fill='x', padx=5, pady=5)

        self.prompt_label = ttk.Label(input_frame, text=f"LOPK {self.current_dir}> ", font=self.font, background='black', foreground='white')
        self.prompt_label.pack(side='left')

        self.command_input = ttk.Entry(input_frame, font=self.font, width=100)
        self.command_input.pack(side='left', expand=True, fill='x', padx=5)
        self.command_input.focus_set()

        # 更新提示符显示当前目录
        self.update_prompt()

        # 绑定回车键执行命令
        self.command_input.bind('<Return>', self.execute_command)

        # 绑定上下箭头键浏览历史命令
        self.command_input.bind('<Up>', self.navigate_history_up)
        self.command_input.bind('<Down>', self.navigate_history_down)

    def append_output(self, text):
        """将文本添加到输出区域"""
        self.output_area.config(state=tk.NORMAL)
        self.output_area.insert(tk.END, text)
        self.output_area.see(tk.END)
        self.output_area.config(state=tk.DISABLED)

    def execute_command(self, event=None):
        """执行用户输入的命令"""
        command = self.command_input.get().strip()
        if not command:
            return

        # 添加到命令历史
        self.command_history.append(command)
        self.history_index = len(self.command_history)
        
        # 添加到命令记录
        self.add_command_record(command, executed=True)

        # 在输出区域显示命令
        self.append_output(f"LOPK> {command}\n")
        self.command_input.delete(0, tk.END)

        # 在新线程中执行命令，避免阻塞GUI
        threading.Thread(target=self.run_command, args=(command,), daemon=True).start()

    def create_menu_bar(self):
        """创建菜单栏"""
        self.menu_bar = tk.Menu(self.root)

        # 文件菜单
        self.file_menu = tk.Menu(self.menu_bar, tearoff=0)
        self.file_menu.add_command(label="清空输出", command=self.clear_output)
        self.file_menu.add_command(label="新建文件", command=self.new_file)
        self.file_menu.add_command(label="导入文件", command=self.import_file)
        self.file_menu.add_separator()
        self.file_menu.add_command(label="退出", command=self.root.quit)
        self.menu_bar.add_cascade(label="文件", menu=self.file_menu)

        # 端口菜单
        self.port_menu = tk.Menu(self.menu_bar, tearoff=0)
        self.port_menu.add_command(label="打开新端口", command=self.open_new_port)
        self.menu_bar.add_cascade(label="端口", menu=self.port_menu)

        # 调试菜单
        self.debug_menu = tk.Menu(self.menu_bar, tearoff=0)
        self.debug_menu.add_command(label="显示调试台", command=lambda: self.notebook.select(self.debug_frame))
        self.debug_menu.add_command(label="清除调试信息", command=self.clear_debug_output)
        self.debug_menu.add_separator()
        self.debug_menu.add_command(label="启用详细调试", command=self.enable_verbose_debug)
        self.debug_menu.add_command(label="禁用详细调试", command=self.disable_verbose_debug)
        self.menu_bar.add_cascade(label="调试", menu=self.debug_menu)

        # 命令库菜单
        self.command_library_menu = tk.Menu(self.menu_bar, tearoff=0)
        self.command_library_menu.add_command(label="导入命令库", command=self.import_command_library)
        self.command_library_menu.add_command(label="命令进程查询", command=self.open_command_process_query)
        self.command_library_menu.add_separator()
        self.command_library_menu.add_command(label="命令管理面板", command=self.open_command_manager)
        self.menu_bar.add_cascade(label="命令", menu=self.command_library_menu)

        # UI菜单
        self.ui_menu = tk.Menu(self.menu_bar, tearoff=0)
        self.ui_menu.add_command(label="导入UI配置", command=self.import_ui_config)
        
        # 终端皮肤子菜单
        self.skin_menu = tk.Menu(self.ui_menu, tearoff=0)
        self.skin_menu.add_command(label="默认皮肤", command=lambda: self.apply_skin("default"))
        self.skin_menu.add_command(label="深色皮肤", command=lambda: self.apply_skin("dark"))
        self.skin_menu.add_command(label="蓝色皮肤", command=lambda: self.apply_skin("blue"))
        self.ui_menu.add_cascade(label="终端皮肤", menu=self.skin_menu)
        
        self.menu_bar.add_cascade(label="UI", menu=self.ui_menu)

        # 数据菜单
        self.data_menu = tk.Menu(self.menu_bar, tearoff=0)
        self.data_menu.add_command(label="保存终端数据", command=self.save_terminal_data)
        self.data_menu.add_command(label="下载数据文件", command=self.download_data_file)
        self.menu_bar.add_cascade(label="数据", menu=self.data_menu)


        # 帮助菜单
        self.help_menu = tk.Menu(self.menu_bar, tearoff=0)
        self.help_menu.add_command(label="使用说明", command=self.show_help)
        self.help_menu.add_command(label="关于", command=self.show_about)
        self.menu_bar.add_cascade(label="帮助", menu=self.help_menu)

        # 联系我菜单
        self.contact_menu = tk.Menu(self.menu_bar, tearoff=0)
        self.contact_menu.add_command(label="联系方式", command=self.show_contact_info)
        self.menu_bar.add_cascade(label="联系我", menu=self.contact_menu)

        # 将菜单栏添加到窗口
        self.root.config(menu=self.menu_bar)

    def clear_output(self):
        """清空输出区域"""
        self.output_area.config(state=tk.NORMAL)
        self.output_area.delete(1.0, tk.END)
        self.output_area.config(state=tk.DISABLED)

    def append_debug_output(self, text):
        """将调试信息添加到调试区域"""
        self.debug_area.config(state=tk.NORMAL)
        self.debug_area.insert(tk.END, text)
        self.debug_area.see(tk.END)
        self.debug_area.config(state=tk.DISABLED)

    def clear_debug_output(self):
        """清空调试信息区域"""
        self.debug_area.config(state=tk.NORMAL)
        self.debug_area.delete(1.0, tk.END)
        self.debug_area.config(state=tk.DISABLED)

    def enable_verbose_debug(self):
        """启用详细调试模式"""
        self.verbose_debug = True
        self.append_debug_output("[DEBUG] 已启用详细调试模式\n")

    def disable_verbose_debug(self):
        """禁用详细调试模式"""
        self.verbose_debug = False
        self.append_debug_output("[DEBUG] 已禁用详细调试模式\n")

    def load_command_records(self):
        """加载保存的命令记录"""
        try:
            if os.path.exists(self.command_history_file):
                with open(self.command_history_file, 'r', encoding='utf-8') as f:
                    self.command_records = json.load(f)
                self.append_debug_output(f"[DEBUG] 已加载命令记录: {len(self.command_records)} 条\n")
        except Exception as e:
            self.append_debug_output(f"[DEBUG] 加载命令记录失败: {str(e)}\n")
            self.command_records = []

    def save_command_records(self):
        """保存命令记录到本地文件"""
        try:
            with open(self.command_history_file, 'w', encoding='utf-8') as f:
                json.dump(self.command_records, f, ensure_ascii=False, indent=2)
            self.append_debug_output(f"[DEBUG] 已保存命令记录: {len(self.command_records)} 条\n")
        except Exception as e:
            self.append_debug_output(f"[DEBUG] 保存命令记录失败: {str(e)}\n")

    def add_command_record(self, command, executed=True):
        """添加命令记录"""
        record = {
            "command": command,
            "executed": executed,
            "timestamp": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        }
        # 检查是否已存在相同命令记录
        for r in self.command_records:
            if r["command"] == command and r["executed"] == executed:
                r["timestamp"] = record["timestamp"]  # 更新时间戳
                self.save_command_records()
                return
        
        self.command_records.append(record)
        # 限制记录数量，最多1000条
        if len(self.command_records) > 1000:
            self.command_records = self.command_records[-1000:]
        self.save_command_records()

    def import_ui_config(self):
        """导入UI配置文件"""
        file_path = filedialog.askopenfilename(
            title="选择UI配置文件",
            filetypes=[("JSON文件", "*.json"), ("所有文件", "*.*")]
        )
        if not file_path:
            return  # 用户取消选择
        
        try:
            with open(file_path, 'r', encoding='utf-8') as f:
                ui_config = json.load(f)
            
            # 应用UI配置
            if "font" in ui_config:
                font_config = ui_config["font"]
                self.font = (font_config.get("family", "SimHei"), font_config.get("size", 10))
                self.output_area.config(font=self.font)
                self.debug_area.config(font=self.font)
                self.command_input.config(font=self.font)
                self.prompt_label.config(font=self.font)
                
            if "colors" in ui_config:
                colors = ui_config["colors"]
                if "background" in colors:
                    self.output_area.config(bg=colors["background"])
                    self.debug_area.config(bg=colors["background"])
                    self.prompt_label.config(background=colors["background"])
                if "foreground" in colors:
                    self.output_area.config(fg=colors["foreground"])
                    self.debug_area.config(fg=colors["foreground"])
                    self.prompt_label.config(foreground=colors["foreground"])
            
            self.append_output(f"成功导入UI配置: {file_path}\n")
            self.append_debug_output(f"[DEBUG] 成功应用UI配置: {file_path}\n")
            messagebox.showinfo("成功", "UI配置导入成功")
            
        except Exception as e:
            error_msg = f"导入UI配置失败: {str(e)}"
            self.append_debug_output(f"[DEBUG] {error_msg}\n")
            messagebox.showerror("错误", error_msg)

    def apply_skin(self, skin_name):
        """应用指定的终端皮肤配置"""
        # 定义内置皮肤配置
        skins = {
            "default": {
                "background": "white",
                "foreground": "black",
                "font": ("SimHei", 10)
            },
            "dark": {
                "background": "#2d2d2d",
                "foreground": "#ffffff",
                "font": ("SimHei", 10)
            },
            "blue": {
                "background": "#e6f2ff",
                "foreground": "#003366",
                "font": ("SimHei", 10)
            }
        }

        if skin_name not in skins:
            self.append_debug_output(f"[DEBUG] 皮肤配置 {skin_name} 不存在\n")
            return

        skin = skins[skin_name]
        # 应用字体设置
        self.font = skin["font"]
        self.output_area.config(font=self.font)
        self.debug_area.config(font=self.font)
        self.command_input.config(font=self.font)
        self.prompt_label.config(font=self.font)

        # 应用颜色设置
        self.output_area.config(bg=skin["background"], fg=skin["foreground"])
        self.debug_area.config(bg=skin["background"], fg=skin["foreground"])
        self.prompt_label.config(background=skin["background"], foreground=skin["foreground"])

        self.append_output(f"已应用 {skin_name} 皮肤配置\n")
        self.append_debug_output(f"[DEBUG] 成功应用 {skin_name} 皮肤配置\n")

    def new_file(self):
        """新建文件"""
        filename = simpledialog.askstring("新建文件", "请输入文件名:")
        if filename:
            try:
                with open(filename, 'w', encoding='utf-8') as f:
                    f.write("")
                self.append_output(f"已创建新文件: {filename}\n")
                self.append_debug_output(f"[DEBUG] 新建文件成功: {filename}\n")
                messagebox.showinfo("成功", f"文件 '{filename}' 创建成功")
            except Exception as e:
                error_msg = f"创建文件失败: {str(e)}"
                self.append_debug_output(f"[DEBUG] {error_msg}\n")
                messagebox.showerror("错误", error_msg)

    def import_file(self):
        """导入文件"""
        file_path = filedialog.askopenfilename(
            title="选择文件",
            filetypes=[("所有文件", "*.*")]
        )
        if not file_path:
            return
            
        try:
            with open(file_path, 'r', encoding='utf-8') as f:
                content = f.read()
            self.append_output(f"文件内容:\n{content}\n")
            self.append_debug_output(f"[DEBUG] 导入文件成功: {file_path}\n")
            messagebox.showinfo("成功", f"文件 '{file_path}' 导入成功")
        except Exception as e:
            error_msg = f"导入文件失败: {str(e)}"
            self.append_debug_output(f"[DEBUG] {error_msg}\n")
            messagebox.showerror("错误", error_msg)

    def import_command_library(self):
        """导入命令库文件"""
        file_path = filedialog.askopenfilename(
            title="选择命令库文件",
            filetypes=[("JSON文件", "*.json"), ("所有文件", "*.*")]
        )
        if not file_path:
            return  # 用户取消选择
        
        try:
            with open(file_path, 'r', encoding='utf-8') as f:
                data = json.load(f)
            
            # 验证命令库格式
            if "commands" not in data or not isinstance(data["commands"], list):
                raise ValueError("命令库文件格式不正确，缺少commands数组")
            
            # 解析命令
            new_commands = {}
            for cmd in data["commands"]:
                if isinstance(cmd, dict) and "name" in cmd and "command" in cmd:
                    new_commands[cmd["name"]] = cmd["command"]
            
            if not new_commands:
                messagebox.showwarning("警告", "未找到有效的命令")
                return
            
            # 更新命令库
            self.command_library.update(new_commands)
            self.append_debug_output(f"[DEBUG] 成功导入命令库，共 {len(new_commands)} 条命令\n")
            self.append_output(f"成功导入命令库: {file_path}，新增 {len(new_commands)} 条命令\n")
            
            # 更新菜单
            self._update_command_library_menu()
            
        except Exception as e:
            error_msg = f"导入命令库失败: {str(e)}"
            self.append_debug_output(f"[DEBUG] {error_msg}\n")
            messagebox.showerror("错误", error_msg)

    def _update_command_library_menu(self):
        """更新命令库菜单"""
        # 清除现有命令（保留导入选项）
        while self.command_library_menu.index("end") >= 0:
            self.command_library_menu.delete(0)
        
        # 添加导入选项和分隔符
        self.command_library_menu.add_command(label="导入命令库", command=self.import_command_library)
        if self.command_library:
            self.command_library_menu.add_separator()
            
            # 添加命令列表
            for name, cmd in self.command_library.items():
                self.command_library_menu.add_command(
                    label=name,
                    command=lambda c=cmd: self._execute_library_command(c)
                )

    def _execute_library_command(self, command):
        """执行从命令库导入的命令"""
        self.command_input.delete(0, tk.END)
        self.command_input.insert(0, command)
        self.execute_command()
        # 添加到命令记录
        self.add_command_record(command, executed=True)

    def show_help(self):
        """显示使用帮助"""
        help_text = "LOPK终端使用说明:\n\n"
        help_text += "1. 基本操作:\n"
        help_text += "   - 在命令输入框中输入命令并按回车键执行\n"
        help_text += "   - 使用上下箭头键浏览命令历史\n"
        help_text += "   - 支持cd命令切换目录\n\n"
        help_text += "2. 菜单功能:\n"
        help_text += "   - 文件: 清空输出、退出程序\n"
        help_text += "   - 端口: 打开新端口连接\n"
        help_text += "   - 调试: 查看调试信息、控制调试模式\n"
        help_text += "   - 命令库: 导入和使用预设命令\n\n"
        help_text += "3. 快捷键:\n"
        help_text += "   - Enter: 执行命令\n"
        help_text += "   - 上箭头: 上一条历史命令\n"
        help_text += "   - 下箭头: 下一条历史命令\n"
        messagebox.showinfo("使用帮助", help_text)

    def save_terminal_data(self):
        """保存终端数据到文件"""
        file_path = filedialog.asksaveasfilename(
            defaultextension=".txt",
            filetypes=[("文本文件", "*.txt"), ("所有文件", "*.*")],
            title="保存终端数据"
        )
        if not file_path:
            return
            
        try:
            # 获取终端输出内容
            terminal_content = self.output_area.get(1.0, tk.END)
            with open(file_path, 'w', encoding='utf-8') as f:
                f.write(terminal_content)
            
            self.append_output(f"终端数据已保存到: {file_path}\n")
            self.append_debug_output(f"[DEBUG] 终端数据保存成功: {file_path}\n")
            messagebox.showinfo("成功", f"数据已成功保存到 '{file_path}'")
        except Exception as e:
            error_msg = f"保存数据失败: {str(e)}"
            self.append_debug_output(f"[DEBUG] {error_msg}\n")
            messagebox.showerror("错误", error_msg)

    def download_data_file(self):
        """下载数据文件"""
        # 这里实现下载功能，示例为保存当前目录信息
        file_path = filedialog.asksaveasfilename(
            defaultextension=".txt",
            filetypes=[("文本文件", "*.txt"), ("JSON文件", "*.json")],
            title="下载数据文件"
        )
        if not file_path:
            return
            
        try:
            # 获取当前目录信息作为示例数据
            dir_info = f"当前目录: {self.current_dir}\n\n目录内容:\n"
            for item in os.listdir(self.current_dir):
                dir_info += f"- {item}\n"
            
            with open(file_path, 'w', encoding='utf-8') as f:
                f.write(dir_info)
            
            self.append_output(f"数据文件已下载到: {file_path}\n")
            self.append_debug_output(f"[DEBUG] 数据文件下载成功: {file_path}\n")
            messagebox.showinfo("成功", f"数据文件已成功下载到 '{file_path}'")
        except Exception as e:
            error_msg = f"下载数据文件失败: {str(e)}"
            self.append_debug_output(f"[DEBUG] {error_msg}\n")
            messagebox.showerror("错误", error_msg)

    def open_command_process_query(self):
        # 创建进程查询窗口
        self.process_window = tk.Toplevel(self.root)
        self.process_window.title("命令进程查询")
        self.process_window.geometry("800x500")
        self.process_window.resizable(True, True)

        # 创建刷新按钮
        refresh_btn = tk.Button(self.process_window, text="刷新进程列表", command=self.refresh_process_list)
        refresh_btn.pack(pady=10)

        # 创建Treeview组件用于显示进程信息
        columns = ("pid", "name", "session_name", "session", "mem_usage")
        self.process_tree = ttk.Treeview(self.process_window, columns=columns, show="headings")

        # 设置列宽和标题
        self.process_tree.column("pid", width=80, anchor="center")
        self.process_tree.column("name", width=250, anchor="w")
        self.process_tree.column("session_name", width=100, anchor="center")
        self.process_tree.column("session", width=80, anchor="center")
        self.process_tree.column("mem_usage", width=120, anchor="center")

        self.process_tree.heading("pid", text="进程ID")
        self.process_tree.heading("name", text="进程名称")
        self.process_tree.heading("session_name", text="会话名称")
        self.process_tree.heading("session", text="会话ID")
        self.process_tree.heading("mem_usage", text="内存使用")

        # 添加滚动条
        scrollbar = ttk.Scrollbar(self.process_window, orient="vertical", command=self.process_tree.yview)
        self.process_tree.configure(yscroll=scrollbar.set)

        # 布局
        self.process_tree.pack(side="left", fill="both", expand=True, padx=10, pady=10)
        scrollbar.pack(side="right", fill="y")

        # 首次加载进程列表
        self.refresh_process_list()

    def refresh_process_list(self):
        # 清空现有列表
        for item in self.process_tree.get_children():
            self.process_tree.delete(item)

        try:
            # 执行tasklist命令获取进程信息
            result = subprocess.run(
                ["tasklist", "/fo", "csv", "/nh"],
                capture_output=True,
                text=True,
                encoding="gbk"
            )

            if result.returncode != 0:
                messagebox.showerror("错误", f"获取进程信息失败: {result.stderr}")
                return

            # 解析CSV格式的输出
            output_lines = result.stdout.strip().split('\n')
            for line in output_lines:
                # 使用正则表达式处理CSV格式，考虑带引号的字段
                parts = re.findall(r'"([^"]*)"|([^,]+)', line)
                # 提取非空部分
                row = [part[0] if part[0] else part[1] for part in parts]
                # 只添加包含PID的有效行
                if len(row) >= 5 and row[1].isdigit():
                    self.process_tree.insert('', "end", values=(
                        row[1],  # PID
                        row[0],  # 名称
                        row[2],  # 会话名称
                        row[3],  # 会话ID
                        row[4]   # 内存使用
                    ))

            self.append_debug_output(f"已加载 {len(output_lines)} 个进程信息\n")

        except Exception as e:
            self.append_debug_output(f"进程查询错误: {str(e)}\n")
            messagebox.showerror("错误", f"获取进程信息时发生错误: {str(e)}")

    def open_command_manager(self):
        """打开命令管理面板"""
        manager_window = tk.Toplevel(self.root)
        manager_window.title("命令管理面板")
        manager_window.geometry("600x400")
        manager_window.resizable(True, True)
        
        # 创建标签页
        notebook = ttk.Notebook(manager_window)
        notebook.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
        
        # 已执行命令标签页
        executed_frame = ttk.Frame(notebook)
        notebook.add(executed_frame, text="已执行命令")
        
        # 未执行命令标签页
        unexecuted_frame = ttk.Frame(notebook)
        notebook.add(unexecuted_frame, text="未执行命令")
        
        # 所有命令标签页
        all_frame = ttk.Frame(notebook)
        notebook.add(all_frame, text="所有命令")
        
        # 创建命令列表
        self._create_command_list(executed_frame, lambda r: r["executed"])
        self._create_command_list(unexecuted_frame, lambda r: not r["executed"])
        self._create_command_list(all_frame, lambda r: True)
        
        # 添加新命令按钮
        ttk.Button(manager_window, text="添加新命令", command=lambda: self.add_new_command(manager_window)).pack(pady=5)

    def _create_command_list(self, parent, filter_func):
        """创建命令列表"""
        # 创建框架
        frame = ttk.Frame(parent)
        frame.pack(fill=tk.BOTH, expand=True)
        
        # 创建列表框
        columns = ("timestamp", "command", "actions")
        tree = ttk.Treeview(frame, columns=columns, show="headings")
        
        # 设置列标题
        tree.heading("timestamp", text="时间")
        tree.heading("command", text="命令")
        tree.heading("actions", text="操作")
        
        # 设置列宽
        tree.column("timestamp", width=150)
        tree.column("command", width=300)
        tree.column("actions", width=100)
        
        # 添加滚动条
        scrollbar = ttk.Scrollbar(frame, orient=tk.VERTICAL, command=tree.yview)
        tree.configure(yscroll=scrollbar.set)
        
        # 布局
        tree.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        
        # 填充数据
        filtered_records = [r for r in self.command_records if filter_func(r)]
        # 按时间戳排序，最新的在前面
        filtered_records.sort(key=lambda x: x["timestamp"], reverse=True)
        
        for record in filtered_records:
            # 创建操作按钮
            action_frame = ttk.Frame(tree)
            
            # 执行按钮
            execute_btn = ttk.Button(action_frame, text="执行", 
                                    command=lambda cmd=record["command"]: self.execute_saved_command(cmd))
            execute_btn.pack(side=tk.LEFT, padx=2)
            
            # 删除按钮
            delete_btn = ttk.Button(action_frame, text="删除", 
                                   command=lambda cmd=record["command"]: self.delete_command_record(cmd, tree))
            delete_btn.pack(side=tk.LEFT, padx=2)
            
            # 添加到树中
            tree.insert("", tk.END, values=(record["timestamp"], record["command"], ""))
            # 将按钮框架添加到单元格
            tree.set(tree.get_children()[-1], "actions", action_frame)
        
        return tree

    def execute_saved_command(self, command):
        """执行保存的命令"""
        self.command_input.delete(0, tk.END)
        self.command_input.insert(0, command)
        self.execute_command()
        # 更新命令记录为已执行
        for record in self.command_records:
            if record["command"] == command:
                record["executed"] = True
                record["timestamp"] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                self.save_command_records()
                break

    def delete_command_record(self, command, tree):
        """删除命令记录"""
        # 从数据中删除
        self.command_records = [r for r in self.command_records if r["command"] != command]
        self.save_command_records()
        
        # 从树中删除
        for item in tree.get_children():
            if tree.item(item)["values"][1] == command:
                tree.delete(item)
                break

    def add_new_command(self, parent_window):
        """添加新命令对话框"""
        dialog = tk.Toplevel(parent_window)
        dialog.title("添加新命令")
        dialog.geometry("400x150")
        dialog.resizable(False, False)
        dialog.transient(parent_window)
        dialog.grab_set()
        
        ttk.Label(dialog, text="请输入新命令:").pack(pady=10)
        command_entry = ttk.Entry(dialog, width=50)
        command_entry.pack(pady=5)
        command_entry.focus_set()
        
        def save_new_command():
            command = command_entry.get().strip()
            if command:
                self.add_command_record(command, executed=False)
                dialog.destroy()
                parent_window.destroy()  # 关闭管理面板
                self.open_command_manager()  # 重新打开以刷新数据
        
        button_frame = ttk.Frame(dialog)
        button_frame.pack(pady=10)
        ttk.Button(button_frame, text="保存", command=save_new_command).pack(side="left", padx=5)
        ttk.Button(button_frame, text="取消", command=dialog.destroy).pack(side="left", padx=5)

    def show_about(self):
        """显示关于信息"""
        about_text = "LOPK终端 v2.0\n"
        about_text += "强大的图形界面命令行工具\n\n"
        about_text += "核心功能:\n"
        about_text += "• 命令执行与实时结果显示\n"
        about_text += "• 命令历史记录与快速导航\n"
        about_text += "• 多标签页界面(终端/调试)\n"
        about_text += "• 文件管理(新建/导入/保存/下载)\n"
        about_text += "• 端口连接与管理\n"
        about_text += "• 命令库导入与快速执行\n"
        about_text += "• UI主题自定义配置\n\n"
        about_text += "技术架构:\n"
        about_text += "Python 3.8+ | Tkinter GUI | 多线程处理\n\n"
        about_text += "© 2024 LOPK终端开发团队 | 版本: 2.0.0" 
        messagebox.showinfo("关于LOPK终端", about_text)

    def show_contact_info(self):
        messagebox.showinfo("联系方式", "联系电话：13535231665")

    def open_new_port(self):
        """打开新端口对话框"""
        port_dialog = tk.Toplevel(self.root)
        port_dialog.title("打开新端口")
        port_dialog.geometry("300x150")
        port_dialog.resizable(False, False)
        
        ttk.Label(port_dialog, text="请输入端口号:", font=self.font).pack(pady=10)
        port_entry = ttk.Entry(port_dialog, font=self.font)
        port_entry.pack(pady=5)
        port_entry.focus_set()
        
        def connect_port():
            port = port_entry.get().strip()
            if port.isdigit() and 1 <= int(port) <= 65535:
                self.append_output(f"正在连接端口 {port}...\n")
                # 这里可以添加实际连接端口的逻辑
                port_dialog.destroy()
            else:
                tk.messagebox.showerror("错误", "请输入1-65535之间的有效端口号")
        
        button_frame = ttk.Frame(port_dialog)
        button_frame.pack(pady=10)
        ttk.Button(button_frame, text="连接", command=connect_port).pack(side="left", padx=5)
        ttk.Button(button_frame, text="取消", command=port_dialog.destroy).pack(side="left", padx=5)

    def run_command(self, command):
        """在后台线程中运行命令并捕获输出，包含调试信息"""
        # 记录调试信息
        debug_msg = f"[DEBUG] 执行命令: {command}\n"
        debug_msg += f"[DEBUG] 工作目录: {self.current_dir}\n"
        self.root.after(0, lambda: self.append_debug_output(debug_msg))

        # 处理cd命令
        if command.startswith('cd '):
            path = command[3:].strip()
            new_dir = os.path.abspath(os.path.join(self.current_dir, path))
            self.root.after(0, lambda: self.append_debug_output(f"[DEBUG] 尝试切换目录: {new_dir}\n"))
            if os.path.isdir(new_dir):
                self.current_dir = new_dir
                output = f"已切换到目录: {self.current_dir}\n"
                self.root.after(0, lambda: self.append_debug_output(f"[DEBUG] 目录切换成功\n"))
            else:
                output = f"目录不存在: {new_dir}\n"
                self.root.after(0, lambda: self.append_debug_output(f"[DEBUG] 目录切换失败: 目录不存在\n"))
            self.root.after(0, lambda: self.append_output(output))
            self.root.after(0, self.update_prompt)
            return

        try:
            # 对于Windows系统，使用cmd.exe执行命令
            self.root.after(0, lambda: self.append_debug_output(f"[DEBUG] 启动子进程执行命令...\n"))
            result = subprocess.run(
                command, shell=True, check=True, stdout=subprocess.PIPE,
                stderr=subprocess.STDOUT, text=True, encoding='gbk', timeout=30,
                cwd=self.current_dir
            )
            output = result.stdout
            self.root.after(0, lambda: self.append_debug_output(f"[DEBUG] 命令执行成功，返回码: {result.returncode}\n"))
            if self.verbose_debug:
                self.root.after(0, lambda: self.append_debug_output(f"[DEBUG] 命令输出:\n{output}\n"))
        except subprocess.CalledProcessError as e:
            output = f"命令执行错误: {e.output}"
            self.root.after(0, lambda: self.append_debug_output(f"[DEBUG] 命令执行错误，返回码: {e.returncode}\n错误输出: {e.output}\n"))
        except subprocess.TimeoutExpired:
            output = "命令执行超时"
            self.root.after(0, lambda: self.append_debug_output(f"[DEBUG] 命令执行超时\n"))
        except Exception as e:
            output = f"发生错误: {str(e)}"
            self.root.after(0, lambda: self.append_debug_output(f"[DEBUG] 发生异常: {str(e)}\n"))

        # 将输出添加到GUI（需要在主线程中执行）
        self.root.after(0, lambda: self.append_output(f"{output}\n"))
        self.root.after(0, self.update_prompt)

    def update_prompt(self):
        """更新提示符显示当前目录"""
        self.prompt_label.config(text=f"LOPK {self.current_dir}> ")

    def navigate_history_up(self, event):
        """向上浏览命令历史"""
        if self.history_index > 0:
            self.history_index -= 1
            self.command_input.delete(0, tk.END)
            self.command_input.insert(0, self.command_history[self.history_index])
        return 'break'  # 阻止事件传播

    def navigate_history_down(self, event):
        """向下浏览命令历史"""
        if self.history_index < len(self.command_history) - 1:
            self.history_index += 1
            self.command_input.delete(0, tk.END)
            self.command_input.insert(0, self.command_history[self.history_index])
        else:
            self.history_index = len(self.command_history)
            self.command_input.delete(0, tk.END)
        return 'break'  # 阻止事件传播

if __name__ == "__main__":
    root = tk.Tk()
    terminal = LOPKTerminal(root)
    root.mainloop()